home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / cp3.arc / CUTPAST3.ASM next >
Assembly Source File  |  1987-05-31  |  26KB  |  872 lines

  1.       PAGE 55,132
  2.       TITLE CUTPASTE 3.0
  3. ;
  4. ; CUTPASTE -
  5. ;      Permission is granted to copy and distribute freely copies of this
  6. ;      program with the following restrictions:
  7. ;
  8. ;      1) this program be passed in the public domain
  9. ;      2) a fee, beyond the cost of the disk, not be charged
  10. ;      3) improvements not be passed on but rather sent to us
  11. ;       to check for possible incompatibilities with other programs
  12. ;
  13. ;   Gerry Boyd, Larry Weiss, (Stephen) Randy Davis
  14. ;   (214) 238-9545  POB 831420 Richardson, Texas 75083           
  15.       
  16. ;PARAMETERS -- MOST OF THESE MAY BE CHANGED TO ANY DESIRED VALUE
  17.  
  18. wndw_ht    equ 25             ;the size of the screen
  19. wndw_wd    equ 80
  20. cut_key    equ  07000H        ;scan code - ascii of cut (Alt-F9)
  21. paste_key  equ  06600H        ;scan code - ascii of paste (Cntrl-F9)
  22.                                 ;now scan codes of edit keys
  23. up_arrow   equ  4800H
  24. down_arrow equ  5000H
  25. left_arrow equ  4B00H
  26. right_arrow equ 4D00H
  27. del_left   equ  0008H         ;user rubout (^H) key
  28. delete     equ  5300H         ;use del (lower right)
  29. insert     equ  5200H
  30. cr         equ  000DH
  31. home       equ  4700H
  32. escape     equ  001BH
  33. tab        equ  7400H         ; ^right arrow
  34. rev_tab    equ  7300H         ; ^left arrow
  35. line_ins   equ  5100H         ;pg down
  36. line_del   equ  4900H         ;pg up
  37. mark_char  equ  4F00H         ;end key
  38.  
  39. blank      equ  00720H       ;define the character which is a blank
  40. attrib     equ  007H         ;and our default attribute (should agree with blank)
  41. video      equ  10H          ;video BIOS call
  42. inv_attrib equ  070H         ;inverse of 'attrib'
  43.     PAGE
  44. CSEG  SEGMENT PARA PUBLIC 'CODE'
  45.       ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:NOTHING   ;STANDARD DECL FOR .COM FILE
  46.  
  47.       ORG  100H
  48.  
  49. Start:
  50.       JMP INSTALL
  51.  
  52. ;PLACE DATA AREA HERE FOR READIBILITY
  53.  
  54. COPYRITE    DB 'Copyright Gerry Boyd, Larry Weiss, Randy Davis 1985  All Rights Reserved'
  55.                 DB '(214)238-9545'
  56. SCREENSAVE: DW (WNDW_HT * (WNDW_WD+1)) DUP (BLANK);RESERVE SPACE TO SAVE OPENED WINDOW
  57. LINESAVE:   DW WNDW_WD DUP (BLANK) ;BUFFER FOR LINE DELETE
  58.  
  59. CURSOR_POS  DW 0
  60. OLD_CUR_POS DW 0
  61. SAVESTACK   DW 0,0
  62.  
  63. REQUEST     DW 0              ;REQUEST TYPE
  64.  
  65. KEY_RQST_HANDLER DD 0         ;ADDRESS OF THE ORIGINAL KEYBOARD REQUEST HANDLER
  66.  
  67. LEFT_MARG  DB   00            ;define the confines of the window
  68. RIGHT_MARG DB   00
  69. TOP_MARG   DB   00
  70. BOT_MARG   DB   00
  71. UPPER_LEFT DW   00
  72.  
  73. MARK       DW   -1            ;FLAGS USED IN CHARACTER FEED
  74. FEED_START DW   00            ;ADDRESS IN BUFFER OF BEGIN...
  75. FEED_STOP  DW   00            ;...AND END OF FEED
  76. FEED_END1  DW   00            ;TEMP HOLDING SPOT FOR BEG FEED ADDR
  77. FEED_END2  DW   00            ;TEMP HOLDING SPOT FOR END FEED ADDR
  78.  
  79. FEED_CHAR  DW   00            ;CHAR TO FEED ON THIS CALL
  80.  
  81. DISPLAY_SEG DW 00             ;SAVE OFF THE DISPLAY SEGMENT ***
  82. PAGE
  83. BEGIN PROC FAR                ;FAR LABEL SINCE ITS ENTERED BY INTERRUPT
  84. MAINLOOP:
  85.       MOV  CS:REQUEST,AX      ;SAVE HIS AX REGISTER
  86.  
  87.       MOV  AX,CS:FEED_START   ;ARE WE IN THE MIDDLE OF FEEDING CHARS...
  88.       CMP  AX,CS:FEED_STOP    ;...TO THE APPLICATION?
  89.       JZ   NOFEED             ;NO
  90.       JMP  FEED               ;YES
  91. NOFEED:
  92.       MOV  AX,CS:REQUEST      ;RESTORE USERS AX
  93.       PUSHF                   ;CALL OLD INTERRUPT HANDLER (EMULATE INT INSTRUCTION)
  94.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;GO AHEAD AND GET THE CHARACTER
  95.       PUSHF                   ;SAVE THE FLAG RETURNED (FOR AH = 1 REQUESTS)
  96.  
  97.       CMP CS:BYTE PTR REQUEST+1,00H ;WE ARE ONLY INTERESTED IN CHAR. REQUESTS
  98.       JZ  CNTINUE
  99.       JMP FORGET_IT
  100.  
  101. CNTINUE:                      ;YES -- CHECK CHARACTER FOR 'OURS'
  102.       POPF                    ;FOR NON-TYPE 1 REQUESTS DONT NEED TO SAVE FLAGS
  103.       CMP AX,CUT_KEY
  104.       JZ  CNT_AGIN
  105.       CMP AX,PASTE_KEY
  106.       JZ  PASTE_CHAR
  107.  
  108.       JMP RETURN_CHAR
  109.  
  110. CNT_AGIN:                     ;WE GOT IT! GO INTO EDITOR MODE
  111.       MOV CS:SAVESTACK,SP
  112.       MOV CS:SAVESTACK+2,SS
  113.       MOV  AX,CS
  114.       MOV  SS,AX
  115.       MOV  SP,100H
  116.  
  117.       STI                     ;ENABLE INTERRUPTS WHILE PROCESSING CHARACTERS
  118.  
  119.       PUSH BP                 ;SET UP A STACK FRAME
  120.       MOV  BP,SP
  121.       SUB  SP,0EH
  122.       CALL SAVEREG
  123.       MOV  DS,AX
  124.  
  125.       CALL CALC_WINDOW        ;CALCULATE WINDOW EXTREMETIES
  126.  
  127.       CALL READ_CURSOR
  128.       MOV OLD_CUR_POS,DX      ;SAVE THE CURSOR FOR LATER RESTORING
  129.  
  130.       CALL WINDOW_SAVE        ;SAVE SCREEN
  131.  
  132.       MOV DX,CURSOR_POS       ;RESTORE CURSOR IN EDIT WINDOW
  133.       CALL PLACE_CURSOR
  134.  
  135.       CALL EDITOR             ;LET HIM EDIT IN THE WINDOW
  136.  
  137.       CALL READ_CURSOR
  138.       MOV CURSOR_POS,DX       ;SAVE CURSOR IN EDIT WINDOW FOR NEXT EDIT
  139.  
  140.       CALL WINDOW_SWAP        ;PUT BACK WHATEVER WAS ORIGINALLY THERE
  141.  
  142.       MOV DX,OLD_CUR_POS      ;RESTORE THE CURSOR POSITION
  143.       CALL PLACE_CURSOR
  144.  
  145.       CALL RESTREG
  146.       ADD  SP,0EH
  147.       POP  BP
  148.  
  149.       MOV SS,CS:SAVESTACK+2
  150.       MOV SP,CS:SAVESTACK
  151.  
  152.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  153.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  154.  
  155. PASTE_CHAR:
  156.       MOV  AX,CS:FEED_END1   ;BEGIN TO FEED CHARACTER STRING INTO APPLICATION
  157.       MOV  CS:FEED_START,AX
  158.       MOV  AX,CS:FEED_END2
  159.       MOV  CS:FEED_STOP,AX
  160.  
  161.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  162.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  163.  
  164. RETURN_CHAR:
  165.       IRET                   ;RETURN WITH CHARACTER
  166.  
  167. ;HANDLE REQUEST TYPE 1'S BY FAR RETURNING 2 AND TYPE 2'S BY JUST RETURNING
  168.  
  169. FORGET_IT:
  170.       CMP  CS:BYTE PTR REQUEST+1,1      ;was it a "is char present" request?
  171.       JZ   FI100
  172.  
  173.       POPF                   ;no -- just return whatever BIOS returned
  174.       IRET
  175.  
  176. FI100:
  177.       POPF                   ;yes -- make funny return
  178.       RET 02
  179.       PAGE
  180. ;HERE WE ARE IN THE PROCESS OF FEEDING CHARACTERS TO THE APPLICATION
  181. ;FROM THE WINDOW BUFFER (SCREENSAVE)
  182.  
  183. FEED:
  184.       CMP  CS:BYTE PTR REQUEST+1,1       ;WAS THIS A CHAR TYPE REQUEST?
  185.       JA   KSTAT
  186.                                 ;YES -- RETURN HIM CHAR
  187.       PUSH BX                 ;GET THE NEXT CHARACTER FROM THE BUFFER
  188.       MOV  BX,AX
  189.       MOV  AX,CS:[BX]
  190.       POP  BX
  191.       XOR  AH,AH              ;WE NO LONGER HAVE THE SCAN CODE, BUT ALL
  192.       MOV  CS:FEED_CHAR,AX    ;ARE ASCII ANYWAY
  193.  
  194.       CMP  CS:BYTE PTR REQUEST+1,0       ;IS THIS A 'GET KEYBOARD CHAR' RQST?
  195.       JNZ  FEED_KEY_STAT
  196.  
  197.       ADD  CS:FEED_START,2    ;YES -- MOVE UP THE POINTER BY 1
  198.  
  199.  
  200. ; SKIP ANY TRAILING BLANKS
  201.       PUSH BX
  202.       MOV BX,CS:FEED_START
  203. FEED10:
  204.       CMP BX,CS:FEED_STOP
  205.       JZ  FEED50
  206.       MOV AX,CS:[BX]
  207.       CMP AL,' '
  208.       JZ FEED20
  209.       CMP  AL,00DH
  210.       JNZ FEED50
  211.       MOV CS:FEED_START,BX
  212.       JMP FEED50
  213. FEED20:
  214.       INC BX
  215.       INC BX
  216.       JMP FEED10
  217. FEED50:
  218.       POP BX
  219.  
  220.       MOV AX,CS:FEED_CHAR
  221.         IRET
  222.  
  223. FEED_KEY_STAT:
  224.       STI                     ;NO -- ENABLE INTERRUPTS AND FEED HIM THE
  225.       RET  02                 ;THE Z FLAG CLEAR WITH HIS CHAR
  226.  
  227. KSTAT:
  228.       MOV  AX,CS:REQUEST      ;RESTORE REQUEST TO AH
  229.       PUSHF
  230.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;PERFORM BIOS CALL -- WE DON'T KNOW
  231.                                 ;WHAT HE'S DOING AND WE SHOULDN'T GET IN THE WAY
  232.       IRET                    ;RETURN THE RESULTS TO HIM (WHATEVER THEY ARE)
  233. BEGIN ENDP
  234.       PAGE
  235. BODY  PROC NEAR               ;MAKE SHORT CALLS ONLY TO THE MAIN ROUTINES
  236. CALC_WINDOW:
  237.       MOV AH,0FH              ;FIND OUT VIDEO MODE FOR CALCULATING WINDOW SIZE
  238.       INT VIDEO               ;GO AHEAD AND GET THE CHARACTER
  239.  
  240. ;***SAVE OFF THE VIDEO SEGMENT***
  241.  
  242.       MOV CX,0B000H           ;IS IT MONOCHROME?
  243.       CMP AL,7                ;WELL LOOK FOR MODE 7
  244.       JZ  CW100
  245.       MOV CX,0B800H           ;NO -- ITS GRAPHIX
  246. CW100:
  247.       MOV DISPLAY_SEG,CX      ;SAVE THIS OFF
  248. ;***
  249.  
  250.       DEC AH                  ;THIS IS THE NUMBER OF COLS ON SCREEN
  251.       MOV RIGHT_MARG,AH       ;SET UP RIGHT AND LEFT MARGINS
  252.       SUB AH,(WNDW_WD - 1)
  253.       MOV LEFT_MARG,AH
  254.  
  255.       MOV TOP_MARG,0          ;WE HAVE NO INFORMATION ON NUMBER OF ROWS
  256.       MOV BOT_MARG,WNDW_HT-1  ;SO WE MUST ASSUME SOMETHING NORMAL (IT ISNT
  257.                               ;AS CRITICAL ANYWAY)
  258.  
  259.       MOV AL,AH               ;NOW ADD UPPER_LEFT HAND CORNER VALUE
  260.       XOR AH,AH
  261.       MOV UPPER_LEFT,AX
  262.  
  263.  
  264.       CMP CURSOR_POS,0        ;IF THIS IS THE FIRST TIME WEVE DONE THIS...
  265.       JNZ CW200
  266.       MOV CURSOR_POS,AX       ;...PLACE THE CURSOR IN THE UPPER LEFT HAND CORNER
  267.  
  268. CW200:
  269.       RET
  270.       PAGE
  271. ;***NEW WINDOW_SWAP PROCEDURE AND WINDOW_SAVE COMBINED -- TWO DIFFERENT
  272. ;ENTRY POINTS TELL WHETHER TO DO THE WRITE OR NOT
  273. ;NOTE THAT THIS PROCEDURE DOES NOT BIOS CALLS -- ALL DIRECT WRITES
  274.  
  275. SWAP_SAVE DB 0
  276.  
  277. WINDOW_SAVE:
  278.       MOV SWAP_SAVE,0         ;MARK THIS ENTRY POINT
  279.       JMP WS025
  280.  
  281. WINDOW_SWAP:
  282.         MOV SWAP_SAVE,0FFH       ;MARK THIS DIFFERENT ENTRY POINT
  283.  
  284. WS025:
  285.         MOV CX,WNDW_HT          ;GET THE NUMBER OF ROWS IN WINDOW AREA
  286.       MOV SI,OFFSET SCREENSAVE;START AT BEGINNING OF BUFFER
  287.       MOV ES,DISPLAY_SEG      ;LOAD UP THE VIDEO SEGMENT
  288.       MOV DI,00
  289.       XOR BX,BX
  290. WS050:
  291.       MOV BL,LEFT_MARG        ;START ON THIS LINE AT THE LEFT MARGIN
  292. WS100:
  293.       SHL  BX,1               ;CHANGE THE COLUMN NUMBER TO BYTE POINTER
  294.       MOV  AX,ES:[BX][DI]     ;GET THE NEXT CHARACTER FROM SCREEN
  295.       XCHG AX,[SI]            ;STORE IT AWAY AND WRITE THE SAVED CHARACTER
  296.       ADD  SI,2               ;AND MOVE SAVE POINTER OVER A WORD
  297. ;***HERE IS THE SWAP SAVE CHECK
  298.       CMP  SWAP_SAVE,0        ;IS THIS WINDOW SWAP OR WINDOW SAVE?
  299.       JZ   WS150
  300.                                 ;MUST BE SWAP
  301.       MOV  ES:[BX][DI],AX     ;NOW RESTORE THAT CHARACTER TO THE SCREEN
  302. WS150:
  303. ;***
  304.         SHR      BX,1            ;PUT THE BYTE OFFSET BACK TO COLUMN NUMBER
  305.       INC  BX
  306.       CMP  BL,RIGHT_MARG      ;ARE WE BEYOND THE END OF THE LINE?
  307.       JNA  WS100
  308.                               ;YES -- SKIP DOWN TO NEXT LINE
  309.  
  310.       MOV WORD PTR [SI],000DH     ; SO CR'S ARE FED PROPERLY LATER
  311.       INC SI
  312.       INC SI
  313.  
  314.       SHL  BX,1               ;ADJUST DI BY ONE LINE'S WORTH SO THAT IT
  315.       ADD  DI,BX              ;POINTS TO BEGINNING OF NEXT LINE
  316.       LOOP WS050
  317.       RET
  318.       PAGE
  319. EDITOR:
  320.  
  321. ;check for edit keys (such as insert, delete, etc.)
  322. ;if not one of those, assume its ascii and just insert it in the
  323. ;screen return when AltF10 detected.
  324.  
  325. ED100:
  326.       CALL GET_CHAR         ;read a character from the keyboard
  327.       OR   AL,AL            ;if this is ascii then dont retain scan code
  328.       JZ   ED105
  329.       XOR  AH,AH
  330.  
  331. ED105:
  332.         CALL UNSHADE_SCREEN      ;REMOVE PREVIOUS SHADING (IF ANY)
  333.  
  334.       MOV  BX,CURSOR_POS     ;in many cases we need the cursor position
  335.       CMP  AX,CUT_KEY        ;check for exit
  336.       JNZ  ED110
  337.       JMP  ED800
  338.  
  339. ED110:
  340.       CMP  AX,CR             ;check for each special character individually
  341.       JNZ  ED120
  342.       MOV  BL,LEFT_MARG
  343.       INC  BH
  344.       JMP  ED500
  345. ED120:
  346.       CMP  AX,LEFT_ARROW
  347.       JNZ  ED140
  348.       DEC  BL
  349.       JMP  ED500
  350.  
  351. ED140:
  352.       CMP  AX,RIGHT_ARROW
  353.       JNZ  ED160
  354.       INC  BL
  355.       JMP  ED500
  356.  
  357. ED160:
  358.       CMP   AX,UP_ARROW
  359.       JNZ   ED180
  360.       DEC   BH
  361.       JMP   ED500
  362.  
  363. ED180:
  364.       CMP  AX,DOWN_ARROW
  365.       JNZ  ED200
  366.       INC  BH
  367.       JMP  ED500
  368.  
  369. ED200:
  370.       CMP  AX,HOME
  371.       JNZ  ED205
  372.       MOV  BX,UPPER_LEFT
  373.       JMP  ED500
  374.  
  375. ED205:                       ;tab and back tab functions
  376.       CMP  AX,TAB
  377.       JNZ  ED210
  378.       MOV  CL,1              ;go forward
  379.       JMP  ED213
  380.  
  381. ED210:
  382.       CMP  AX,REV_TAB
  383.       JNZ  ED220
  384.  
  385.       MOV  CL,0FFH           ;go backwards one tab slot
  386.       ADD  DL,CL             ;start one char to left initially
  387.  
  388. ED213:
  389.       CALL READ_CHAR         ;get char at current position
  390.       MOV  CH,AL             ;save it for comparison
  391. ED215:
  392.       ADD  DL,CL             ;move over one character
  393.       CMP  DL,RIGHT_MARG     ;stop at left and right margins (or beyond)
  394.       JGE  ED218
  395.       CMP  DL,LEFT_MARG
  396.       JLE  ED218
  397.  
  398.       CALL READ_CHAR         ;read current character
  399.       CMP  CH,' '            ;if original was a space...
  400.       JNZ  ED216
  401.       CMP  AL,' '            ;...then go until not space
  402.       JZ  ED215
  403.       JMP ED217
  404. ED216:
  405.       CMP AL,' '             ;...else, go until space
  406.       JNZ ED215
  407. ED217:
  408.       CMP  CL,0FFH           ;if we were going backwards (towards left)...
  409.       JNZ  ED218
  410.       ADD  DL,1              ;...then scoot back to the right by 1
  411. ED218:
  412.       MOV  BX,DX
  413.       JMP  ED500
  414.  
  415. ED220:
  416.       CMP  AX,ESCAPE         ;wipe out remainder of line
  417.       JNZ  ED240
  418.       MOV  DX,BX
  419.       CALL ERASE_LINE
  420.       JMP  ED500
  421.  
  422. ED240:
  423.       CMP  AX,DEL_LEFT       ;move cursor left one char and then do normal del
  424.       JNZ  ED260
  425.       DEC  BL
  426.       CMP  BL,LEFT_MARG
  427.       JNB  ED250
  428.       MOV  BL,RIGHT_MARG
  429.       CMP  BH,00
  430.       JZ   ED250
  431.       DEC  BH
  432. ED250:
  433.       JMP  ED270
  434.  
  435. ED260:
  436.       CMP  AX,DELETE         ;in delete char we...
  437.       JNZ  ED280
  438. ED270:
  439.       MOV  CL,RIGHT_MARG
  440.       SUB  CL,BL             ;calculate how many chars to right margin
  441.       XOR  CH,CH
  442.       MOV  DX,BX             ;...start at current cursor position...
  443.       JCXZ ED275
  444. ED272:
  445.       INC  DL                ;...get character just to the right...
  446.       CALL READ_CHAR
  447.       DEC  DL                ;...move left one position...
  448.       CALL WRITE_CHAR        ;...and write it there...
  449.       INC  DL                ;...now do it again for the char to the right...
  450.       LOOP ED272             ;...for the distance from cursor to right margin;...
  451. ED275:
  452.       MOV  AX,BLANK
  453.       CALL WRITE_CHAR
  454.       JMP  ED500
  455.  
  456. ED280:
  457.       CMP  AX,INSERT         ;in the case of insert we do reverse of delete
  458.       JNZ  ED300
  459.       MOV  DH,BH             ;start at the right margin
  460.       MOV  DL,RIGHT_MARG
  461.       MOV  CL,DL             ;caculate number of spaces to right
  462.       SUB  CL,BL
  463.       XOR  CH,CH
  464.       JCXZ ED290
  465. ED285:
  466.       DEC  DL
  467.       CALL READ_CHAR
  468.       INC  DL
  469.       CALL WRITE_CHAR
  470.       DEC  DL
  471.       LOOP ED285
  472. ED290:
  473.       MOV  AX,BLANK
  474.       CALL WRITE_CHAR
  475.       JMP  ED500
  476.  
  477. ED300:
  478.       CMP  AX,LINE_INS       ;check for insert line
  479.       JNZ  ED320
  480.       MOV  DH,BOT_MARG       ;we're going to need that
  481. ED305:
  482.       MOV  DL,LEFT_MARG      ;always start at the far left
  483.       CMP  DH,BH             ;are we on our current line?
  484.       JZ   ED315
  485.                              ;no -- then move it down
  486.       MOV  CX,WNDW_WD
  487. ED310:
  488.       DEC  DH
  489.       CALL READ_CHAR         ;get the character
  490.       INC  DH
  491.       CALL WRITE_CHAR        ;and put it back one line higher
  492.       INC  DL                ;move right one character
  493.       LOOP ED310
  494.  
  495.       DEC  DH                ;now move up a line and do it again
  496.       JMP  ED305
  497. ED315:
  498.       MOV  BL,LEFT_MARG      ;move us over the far left marg
  499.       CALL ERASE_LINE        ;and wipe out the line we are on
  500.       JMP  ED500
  501.  
  502. ED320:
  503.       CMP  AX,LINE_DEL       ;and check for line delete
  504.       JNZ  ED340
  505.  
  506. ED325:
  507.       MOV  DL,LEFT_MARG      ;always start at the far left
  508.       CMP  DH,BOT_MARG       ;are we on the last line?
  509.       JZ   ED335
  510.                              ;no -- then move it up
  511.       MOV  CX,WNDW_WD
  512. ED330:
  513.       INC  DH
  514.       CALL READ_CHAR         ;get the character
  515.       DEC  DH
  516.       CALL WRITE_CHAR        ;and put it back one line lower
  517.       INC  DL                ;move right one character
  518.       LOOP ED330
  519.  
  520.       INC  DH                ;now move down a line and do it again
  521.       JMP  ED325
  522. ED335:
  523.       MOV  BL,LEFT_MARG      ;move us over the far left marg of our line
  524.       CALL ERASE_LINE        ;and wipe out the bottom line
  525.       JMP  ED500
  526.  
  527. ED340:
  528.       CMP  AX,MARK_CHAR      ;check for mark
  529.       JNZ  ED400
  530.  
  531.       MOV  DX,BX
  532.       CMP  MARK,-1           ;if mark isnt set...
  533.       JNZ  ED350
  534.       MOV  MARK,BX           ;...just set it and switch its attrib
  535.       CALL READ_CHAR
  536.       MOV  AH,ATTRIB
  537.       CALL WRITE_CHAR
  538.       JMP  ED500
  539.  
  540. ED350:                       ;else, store off feed start and end addresses
  541.       CALL CONVERT_LOC
  542.       MOV  FEED_END1,AX
  543.  
  544.       MOV  DX,MARK
  545.       CALL CONVERT_LOC
  546.       MOV  FEED_END2,AX
  547.  
  548.       MOV  CX,FEED_END1
  549.       CMP  CX,AX
  550.       JNA  ED355
  551.       MOV  FEED_END1,AX
  552.       MOV  FEED_END2,CX
  553. ED355:
  554.         CALL TRIM_SCREEN ;TRIM OFF UNMARKED THINGS ON SCREEN
  555.       JMP  ED800             ;note that this char exits the note pad
  556.  
  557. ED400:                       ;wasnt an edit character -- must be ascii
  558.                                 ;just write the character at current position
  559.       MOV  AH,ATTRIB
  560.       CALL W_CHAR
  561.       INC  BL                ;move over one position
  562.  
  563. ED500:                       ;adjust resulting cursor position
  564.       CMP  BL,RIGHT_MARG
  565.       JLE  ED550
  566.       MOV  BL,RIGHT_MARG
  567. ED550:
  568.       CMP  BH,BOT_MARG
  569.       JLE  ED600
  570.       MOV  BH,BOT_MARG
  571. ED600:
  572.       CMP  BL,LEFT_MARG
  573.       JGE  ED650
  574.       MOV  BL,LEFT_MARG
  575. ED650:
  576.       CMP  BH,TOP_MARG
  577.       JGE  ED700
  578.       MOV  BH,TOP_MARG
  579. ED700:
  580.       MOV  CURSOR_POS,BX
  581.       MOV  DX,BX             ;be sure and move the cursor to the new
  582.       CALL PLACE_CURSOR      ;position
  583.       JMP  ED100
  584.  
  585. ED800:                       ;exit
  586.       RET
  587.       PAGE
  588. ;
  589. ; HERE WE PLACE SOME SMALL GENERAL PURPOSE ROUTINES
  590. ;
  591.  
  592. PLACE_CURSOR:                ;place cursor at location in dx
  593.  
  594.       CALL SHADE_SCREEN       ;if we are in mark mode, set the
  595.                                 ;screen square to inverse video
  596.       MOV AH,2H
  597.       PUSH BX
  598.       XOR BX,BX
  599.       INT VIDEO
  600.       POP  BX
  601.       RET
  602.  
  603. UP_LEFT DW 0
  604. LW_RIGHT DW 0
  605. ATTRIBUTE DB 0
  606. SAVE_AX DW 0
  607. SAVE_DX DW 0
  608.  
  609. SHADE_SCREEN:                    ;NEW SCREEN SHADING PROCEDURE
  610.         CMP      MARK,-1H        ;IS A MARK SET?
  611.         JZ       SS_END
  612.                                 ;YES -- OK SWING INTO ACTION
  613.         MOV      SAVE_AX,AX
  614.         MOV      SAVE_DX,DX
  615.         MOV      ATTRIBUTE,INV_ATTRIB ;FIRST SET THE ATTRIBUTE TO INVERSE
  616.         MOV      BX,CURSOR_POS
  617.         MOV     AX,MARK         ;NOW, CALCULATE THE UPPER LEFT CORNER...
  618.         CMP      BL,AL           ;...OF OUR SHADED BOX
  619.         JA       SS100
  620.         MOV      AL,BL
  621. SS100:
  622.         CMP      BH,AH
  623.         JA       SS200
  624.         MOV      AH,BH
  625. SS200:
  626.         MOV      UP_LEFT,AX
  627.         MOV      AX,MARK ;NOW THE LOWER RIGHT CORNER
  628.         CMP      BL,AL
  629.         JB       SS300
  630.         MOV      AL,BL
  631. SS300:
  632.         CMP      BH,AH
  633.         JB       SS400
  634.         MOV      AH,BH
  635. SS400:
  636.         MOV      LW_RIGHT,AX
  637.         JMP      SS_COMMON
  638.  
  639. UNSHADE_SCREEN:
  640.         CMP      MARK,-1H        ;HERE WE UNSHADE THE SHADED AREA
  641.         JZ       SS_END
  642.         MOV      SAVE_AX,AX
  643.         MOV      SAVE_DX,DX
  644.         MOV      ATTRIBUTE,ATTRIB ;CHANGE THE BOX BACK TO NORMAL
  645.  
  646.  
  647. ;NOW BEGIN TO SHADE IN FROM THE UPPER LEFT TO THE LOWER RIGHT CORNERS
  648.  
  649. SS_COMMON:
  650.         MOV      DX,UP_LEFT
  651.         MOV      BX,LW_RIGHT
  652. SS500:
  653.         CMP      DL,BL                   ;ARE WE OFF THE RIGHT END?
  654.         JA       SS600
  655.         MOV      AH,ATTRIBUTE
  656.         CALL     WRITE_ATTRIB
  657.         INC      DL
  658.         JMP      SS500
  659. SS600:
  660.         INC      DH                      ;OK WE WENT OFF THE RIGHT END...
  661.         CMP      DH,BH                   ;...MOVE DOWN ONE AND CHECK LOWER BOUND
  662.         JA       SS700
  663.         MOV      DL,BYTE PTR UP_LEFT
  664.         JMP      SS500
  665. SS700:
  666.         MOV      AX,SAVE_AX
  667.         MOV      DX,SAVE_DX
  668. SS_END:
  669.         RET
  670.  
  671. TRIM_SCREEN:                             ;AFTER HE SELECTS THE SECOND MARK
  672.                                         ;WE TRIM OFF THE RIGHT MARG OF SCREEN
  673.         MOV      MARK,-1H                ;FIRST CLEAR MARK
  674.         MOV      BX,UP_LEFT              ;START WITH THE FIRST LINE
  675.         MOV      BL,BYTE PTR LW_RIGHT
  676. TS100:
  677.         MOV      DX,LW_RIGHT             ;COMPARE THIS WITH THE LAST LINE
  678.         CMP      BH,DH                   ;FINISHED?
  679.         JZ       TS200
  680.         MOV      DX,BX                   ;NO -- ERASE THE END OF THIS LINE
  681.         CALL     ERASE_LINE
  682.         INC      BH                      ;AND CONTINUE ON TO NEXT LINE
  683.         JMP      TS100
  684. TS200:
  685.         RET
  686.  
  687. READ_CURSOR:                  ;read cursor location into dx
  688.       MOV AH,3H
  689.       PUSH BX
  690.       XOR BX,BX
  691.       INT VIDEO
  692.       POP  BX
  693.       RET
  694.  
  695. ;***NEW READ CHAR PROCEDURE***
  696. READ_CHAR:                    ;read screen character at location in dx
  697.       CALL CALC_VID_LOC       ;covert the row and column into location
  698.       MOV  AX,ES:[DI]         ;get the character at that location
  699.       RET
  700. ;***
  701.  
  702. R_CHAR:                       ;read screen char at current cursor location
  703.       MOV AH,8H
  704.       PUSH BX
  705.       XOR BH,BH
  706.       INT VIDEO
  707.       POP  BX
  708.       RET
  709.  
  710. ;***NEW WRITE CHAR PROCEDURE
  711. WRITE_CHAR:                   ;write attrib/char in ax at location in dx
  712.       PUSH AX                 ;save the attrib from destruction
  713.       CALL CALC_VID_LOC       ;convert the row and column into location
  714.       POP  AX
  715.       MOV ES:[DI],AX
  716.       RET
  717. WRITE_ATTRIB:
  718.       PUSH AX
  719.       CALL CALC_VID_LOC
  720.       POP  AX
  721.         MOV ES:01[DI],AH
  722.       RET
  723. ;***
  724.  
  725. W_CHAR:                       ;write character at current cursor location
  726.       PUSH BX                 ;save bx register
  727.       MOV  BL,AH
  728.       XOR  BH,BH
  729.       PUSH CX                 ;retain cx register also
  730.       MOV  CX,1
  731.       MOV  AH,9H
  732.       INT VIDEO
  733.       POP  CX
  734.       POP  BX
  735.       RET
  736.  
  737. GET_CHAR:                     ;get character from keyboard into ax
  738.       MOV AH,0H
  739.       PUSHF                   ;simulate call to keyboard handler
  740.       CALL DWORD PTR [KEY_RQST_HANDLER]
  741.       RET
  742.  
  743. ERASE_LINE:                   ;erase the current line from dx to right margin
  744.       MOV  CL,RIGHT_MARG
  745.       SUB  CL,BL
  746.       INC  CL
  747.       XOR  CH,CH
  748.       MOV  SI,OFFSET LINESAVE
  749.  
  750. ER100:
  751.       CALL READ_CHAR         ;get the character @ current location
  752.       MOV  [SI],AX
  753.       ADD  SI,2
  754.  
  755.       MOV  AX,BLANK
  756.       CALL WRITE_CHAR        ;***CHANGED FROM W_CHAR***
  757.       INC  DL
  758.       LOOP ER100
  759.       RET
  760.  
  761. RESTORE_LINE:                ;restore the current line from dx to right margin
  762.       MOV  CL,RIGHT_MARG
  763.       SUB  CL,BL
  764.       INC  CL
  765.       XOR  CH,CH
  766.       MOV  DI,OFFSET LINESAVE
  767.  
  768. RL100:
  769.       MOV  AX,[DI]           ;get the saved char
  770.       CALL WRITE_CHAR         ;put the saved char where indicated
  771.       ADD  DI,2
  772.       INC  DL
  773.       LOOP RL100
  774.       RET
  775.  
  776. CONVERT_LOC:                 ;convert a location on the screen (in dx) into AX
  777.       MOV  CX,DX
  778.       MOV  AX,OFFSET SCREENSAVE
  779. CL100:
  780.       CMP  CH,TOP_MARG
  781.       JZ   CL200
  782.       ADD  AX,(WNDW_WD+1)*2
  783.       DEC  CH
  784.       JMP  CL100
  785.  
  786. CL200:
  787.       CMP  CL,LEFT_MARG
  788.       JZ   CL300
  789.       ADD  AX,2
  790.       DEC  CL
  791.       JMP  CL200
  792.  
  793. CL300:
  794.       RET
  795.  
  796. SAVEREG:
  797.       MOV  -2[BP],BX          ;save reggies on stack frame
  798.       MOV  -4[BP],CX
  799.       MOV  -6[BP],DX
  800.       MOV  -8[BP],SI
  801.       MOV  -0AH[BP],DI
  802.       MOV  -0CH[BP],DS
  803.       MOV  -0EH[BP],ES       ;***ADDED SAVING OF ES***
  804.       RET
  805. RESTREG:
  806.       MOV  BX,-2[BP]          ;NOW PUT THE REGGIES BACK AND PULL DOWN
  807.       MOV  CX,-4[BP]          ;THE STACK FRAME
  808.       MOV  DX,-6[BP]
  809.       MOV  SI,-8[BP]
  810.       MOV  DI,-0AH[BP]
  811.       MOV  DS,-0CH[BP]
  812.       MOV  ES,-0EH[BP]       ;***ADD RESTORE OF ES***
  813.       RET
  814.  
  815. ;***NEW PROCEDURE TO CONVERT ROW AND COLUMN INTO ADDRESS
  816.  
  817. CALC_VID_LOC:                ;convert the row and column in dx into an
  818.                              ;offset into the video display buffer
  819.       XOR  AX,AX
  820.       XOR  DI,DI
  821.       PUSH CX                ;save cx -- some of those who call us need it
  822.       XOR  CX,CX
  823.  
  824.       MOV  AL,RIGHT_MARG     ;get the width of a row
  825.       INC  AX
  826.       MOV  CL,DH             ;put the number of rows into cx
  827.       JCXZ CVL200
  828. CVL100:
  829.       ADD  DI,AX             ;for every row add in another 80/40 columns
  830.       LOOP CVL100
  831. CVL200:
  832.       MOV  AL,DL             ;now move over to the current column
  833.       ADD  DI,AX
  834.  
  835.       POP  CX                ;restore cx
  836.  
  837.       SHL  DI,1              ;now convert this into byte offset
  838.       MOV  ES,DISPLAY_SEG
  839.       RET
  840. ;***
  841.  
  842. BODY  ENDP
  843.       PAGE
  844. INSTALL:
  845. ;THIS PROGRAM INSTALLS THE REST OF THE CODE FOR NOTE PAD
  846.  
  847.       MOV DX,OFFSET MESSAGE  ;OUTPUT 'OK' MESSAGE
  848.       MOV AH,9H
  849.       INT 21H
  850.  
  851.       MOV AX,3516H            ;GET INTERRUPT 16 VECTOR
  852.       INT 21H
  853.       MOV WORD PTR KEY_RQST_HANDLER,BX
  854.       MOV WORD PTR KEY_RQST_HANDLER+2,ES
  855.  
  856.       MOV AX,2516H
  857.       MOV DX,OFFSET BEGIN     ;NOW PUT OUR ROUTINE THERE
  858.       INT 21H
  859.  
  860.       MOV DX,OFFSET INSTALL   ;TERMINATE AND STAY RESIDENT
  861.       ADD DX,100H
  862.       MOV CL,4
  863.       SHR DX,CL
  864.       MOV AH,31H
  865.       INT 21H
  866.  
  867. MESSAGE DB 10,13,'CUTPASTE 3.0 installed',10,13,' ALT F9 to enable cut',
  868.         DB 10,13,'   ^F9 to paste   ',10,13,'$'
  869.  
  870. CSEG ENDS
  871.      END START
  872.